#include "uart.h"
#include <stdio.h>
#include "hc32f460_usart.h"
/* DMAC */
#define DMA_UNIT (M4_DMA1)
#define DMA_UNIT1 (M4_DMA2)
#define DMA_CH_RX (DmaCh0)
#define DMA_CH_TX (DmaCh1)
#define DMA_TRG_SEL_RX (EVT_USART1_RI)
#define DMA_TRG_SEL_TX (EVT_USART1_TI)
#define DMA_TRG_SEL_RX3 (EVT_USART3_RI)
#define DMA_TRG_SEL_TX3 (EVT_USART3_TI)
/* USART channel definition */
#define USART_CH (M4_USART1)
#define USART3_CH (M4_USART3)
/* USART baudrate definition */
#define USART_BAUDRATE                   (115200ul)//(460800ul)//(921600ul)// (256000)//(921600ul)//(115200ul)//(921600ul)
/* USART RX Port/Pin definition */
#define USART_RX_PORT (PortA)
#define USART_RX_PIN (Pin08)
#define USART3_RX_PORT (PortC)
#define USART3_RX_PIN (Pin13)
#define USART_RX_FUNC (Func_Usart1_Rx)
#define USART3_RX_FUNC (Func_Usart3_Rx)
/* USART TX Port/Pin definition */
#define USART_TX_PORT (PortA)
#define USART_TX_PIN (Pin09)
#define USART3_TX_PORT (PortH)
#define USART3_TX_PIN (Pin02)
#define USART_TX_FUNC (Func_Usart1_Tx)
#define USART3_TX_FUNC (Func_Usart3_Tx)


/************ipr**************/
// USART interrupt definition
#define USART1_RX_ERR_IRQn               (Int002_IRQn)
#define USART1_RX_ERR_INT_SRC            (INT_USART1_EI)
#define USART1_RX_FULL_IRQn              (Int003_IRQn)
#define USART1_RX_FULL_INT_SRC           (INT_USART1_RI)

// USART interrupt definition
#define USART3_RX_ERR_IRQn               (Int000_IRQn)
#define USART3_RX_ERR_INT_SRC            (INT_USART3_EI)
#define USART3_RX_FULL_IRQn              (Int001_IRQn)
#define USART3_RX_FULL_INT_SRC           (INT_USART3_RI)




uint8_t recvBuf[RXBUF_LEN];
const uint8_t * const g_rx = recvBuf;
static uint8_t sendBuf[TXBUF_LEN] = {9,8,7};
uint8_t recv3Buf[RXBUF_LEN];
const uint8_t * const g_rx3 = recv3Buf;
static uint8_t send3Buf[TXBUF_LEN] = {9,8,7};

static void DmaInit(void)
{
    stc_dma_config_t stcDmaInit;

    /* 	Enable peripheral clock		*/
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_DMA1 | PWC_FCG0_PERIPH_DMA2,Enable);

    /* 	Enable DMA.	*/
    DMA_Cmd(DMA_UNIT,Enable);
    DMA_Cmd(DMA_UNIT1,Enable);
								
    //接收						
    /* 	Initialize DMA. 	*/	
    MEM_ZERO_STRUCT(stcDmaInit);
    stcDmaInit.u16BlockSize = 1u; /* 每次启动时传输的数据块（最大1024）,相当于复制一个数据多少次 */
    // stcDmaInit.u16TransferCnt = 10u;
    stcDmaInit.u32SrcAddr = ((uint32_t)(&USART_CH->DR)+2ul); /* Set source address. */
    stcDmaInit.u32DesAddr = (uint32_t)(recvBuf);     /* Set destination address. */
    stcDmaInit.u16DesRptSize = RXBUF_LEN; //重复发送的数据长度
    stcDmaInit.stcDmaChCfg.enSrcInc = AddressFix;  /* 源地址固定 */
    stcDmaInit.stcDmaChCfg.enDesInc = AddressIncrease;  /* 目标地址递增 */
    stcDmaInit.stcDmaChCfg.enDesRptEn = Enable; //是否复位目标地址
    stcDmaInit.stcDmaChCfg.enIntEn = Disable;       /* Enable interrupt. */
    stcDmaInit.stcDmaChCfg.enTrnWidth = Dma8Bit;   /* Set data width 8bit. */
    DMA_InitChannel(DMA_UNIT, DMA_CH_RX, &stcDmaInit);
    // uart3
    stcDmaInit.u32SrcAddr = ((uint32_t)(&USART3_CH->DR)+2ul); /* Set source address. */
    stcDmaInit.u32DesAddr = (uint32_t)(recv3Buf);     /* Set destination address. */
    DMA_InitChannel(DMA_UNIT1, DMA_CH_RX, &stcDmaInit);

    /* Enable the specified DMA channel. */
    DMA_ChannelCmd(DMA_UNIT, DMA_CH_RX, Enable);
    DMA_ChannelCmd(DMA_UNIT1, DMA_CH_RX, Enable);

    /* Clear DMA flag. */
    // DMA_ClearIrqFlag(DMA_UNIT, DMA_CH_RX, TrnCpltIrq);

    /* Enable peripheral circuit trigger function. */
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS,Enable);

    /* Set DMA trigger source. */
    DMA_SetTriggerSrc(DMA_UNIT, DMA_CH_RX, DMA_TRG_SEL_RX);
    DMA_SetTriggerSrc(DMA_UNIT1, DMA_CH_RX, DMA_TRG_SEL_RX3);
				
    // 发送 
    /* Initialize DMA. */
    MEM_ZERO_STRUCT(stcDmaInit);
    stcDmaInit.u16BlockSize = 1u; /* 每次启动时传输的数据块（最大1024）,相当于复制一个数据多少次 */
    // stcDmaInit.u16TransferCnt = 1u;
    stcDmaInit.u32SrcAddr = (uint32_t)(sendBuf); /* Set source address. */
    stcDmaInit.u32DesAddr = (uint32_t)(&USART_CH->DR);     /* Set destination address. */
    // stcDmaInit.u16DesRptSize = 3; //重复发送的数据长度
    stcDmaInit.stcDmaChCfg.enSrcInc = AddressIncrease;  /* 源地址递增 */
    stcDmaInit.stcDmaChCfg.enDesInc = AddressFix;  /* 目标地址固定 */
    // stcDmaInit.stcDmaChCfg.enDesRptEn = Enable; //是否复位目标地址
    // stcDmaInit.stcDmaChCfg.enSrcRptEn = Enable; //是否复位源地址
    stcDmaInit.stcDmaChCfg.enIntEn = Disable;       /* Enable interrupt. */
    stcDmaInit.stcDmaChCfg.enTrnWidth = Dma8Bit;   /* Set data width 8bit. */
    DMA_InitChannel(DMA_UNIT, DMA_CH_TX, &stcDmaInit);
    // uart3
    stcDmaInit.u32SrcAddr = (uint32_t)(send3Buf); /* Set source address. */
    stcDmaInit.u32DesAddr = (uint32_t)(&USART3_CH->DR);     /* Set destination address. */
    DMA_InitChannel(DMA_UNIT1, DMA_CH_TX, &stcDmaInit);

    /* Enable the specified DMA channel. */
    // DMA_ChannelCmd(DMA_UNIT, DMA_CH_TX, Enable);

    /* Clear DMA flag. */
    // DMA_ClearIrqFlag(DMA_UNIT, DMA_CH_TX, TrnCpltIrq);

    /* Set DMA trigger source. */
    DMA_SetTriggerSrc(DMA_UNIT, DMA_CH_TX, DMA_TRG_SEL_TX);
    DMA_SetTriggerSrc(DMA_UNIT1, DMA_CH_TX, DMA_TRG_SEL_TX3);
}

//static void USART3_RxError_IrqCallback(void)
//{
//	if (1 == USART_GetStatus(USART3_CH, (UsartParityErr | UsartFrameErr))) 
//	{
//		(void)USART_RecData(USART3_CH);
//	}
//	USART_ClearStatus(USART3_CH, (UsartParityErr | UsartFrameErr | UsartOverrunErr));
//}

//static void USART1_RxError_IrqCallback(void)
//{
//	//if (SET == USART_GetStatus(USART1_UNIT, (USART_FLAG_PARITY_ERR | USART_FLAG_FRAME_ERR))) 
//	//{
//		(void)USART_RecData(USART_CH);
//	//}
//	USART_ClearStatus(USART_CH,(UsartParityErr | UsartFrameErr | UsartOverrunErr));
//}

//static void USART_RxFull_IrqCallback(void)
//{
//  uint8_t u8Data = (uint8_t)USART_RecData(USART_CH);
//  u8Data = u8Data;
//}

//static void USART3_RxFull_IrqCallback(void)
//{
//  uint8_t u8Data = (uint8_t)USART_RecData(USART3_CH);
//  u8Data = u8Data;
//}

void uartInit(void)
{
    en_result_t enRet = Ok;
	
    //stc_irq_regi_conf_t stcIrqRegiCfg;
	
    uint32_t u32Fcg1Periph = PWC_FCG1_PERIPH_USART1 | PWC_FCG1_PERIPH_USART2 | \
                             PWC_FCG1_PERIPH_USART3 | PWC_FCG1_PERIPH_USART4;
	
    const stc_usart_uart_init_t stcInitCfg = {
        UsartIntClkCkNoOutput,
        UsartClkDiv_1,		
        UsartDataBits8,		
        UsartDataLsbFirst, 	
        UsartOneStopBit,	
        UsartParityNone,	
        UsartSampleBit8,	
        UsartStartBitFallEdge,
        UsartRtsEnable,		
    };
	
    /* Initialize DMA */
    DmaInit();	
				
    /* Enable peripheral clock */
    PWC_Fcg1PeriphClockCmd(u32Fcg1Periph, Enable);						 
																		 
    /* Initialize USART IO */											 
    PORT_SetFunc(USART_RX_PORT, USART_RX_PIN, USART_RX_FUNC, Disable);	 
    PORT_SetFunc(USART_TX_PORT, USART_TX_PIN, USART_TX_FUNC, Disable);	 
    PORT_SetFunc(USART3_RX_PORT, USART3_RX_PIN, USART3_RX_FUNC, Disable);
    PORT_SetFunc(USART3_TX_PORT, USART3_TX_PIN, USART3_TX_FUNC, Disable);

    /* Initialize USART */
    enRet = USART_UART_Init(USART_CH, &stcInitCfg);
    if (enRet != Ok)
    {
        while (1)
        {
        }
    }
    else
    {
    }
    enRet = USART_UART_Init(USART3_CH, &stcInitCfg);
    if (enRet != Ok)
    {
        while (1){;}
    }

    /* Set baudrate */
    enRet = USART_SetBaudrate(USART_CH, USART_BAUDRATE);
    if (enRet != Ok)
    {
        while (1){;}
    }
    enRet = USART_SetBaudrate(USART3_CH, USART_BAUDRATE);
    if (enRet != Ok)
    {
        while (1){;}
    }
	
//	
//	/* Register RX error IRQ handler && configure NVIC. */
//	stcIrqRegiCfg.enIRQn = USART1_RX_ERR_IRQn;
//	stcIrqRegiCfg.enIntSrc = USART1_RX_ERR_INT_SRC;
//	stcIrqRegiCfg.pfnCallback = &USART1_RxError_IrqCallback;
//    INTC_IrqInstalHandler(&stcIrqRegiCfg, DDL_IRQ_PRIORITY_DEFAULT);

//	/* Register RX full IRQ handler && configure NVIC. */
////	stcIrqRegiCfg.enIRQn = USART1_RX_FULL_IRQn;
////	stcIrqRegiCfg.enIntSrc = USART1_RX_FULL_INT_SRC;
////	stcIrqRegiCfg.pfnCallback = &USART_RxFull_IrqCallback;
////    INTC_IrqInstalHandler(&stcIrqRegiCfg, DDL_IRQ_PRIORITY_DEFAULT);
//	
//	/* Register RX error IRQ handler && configure NVIC. */
//	stcIrqRegiCfg.enIRQn = USART3_RX_ERR_IRQn;
//	stcIrqRegiCfg.enIntSrc = USART3_RX_ERR_INT_SRC;
//	stcIrqRegiCfg.pfnCallback = &USART3_RxError_IrqCallback;
//	INTC_IrqInstalHandler(&stcIrqRegiCfg, DDL_IRQ_PRIORITY_DEFAULT);

//	/* Register RX full IRQ handler && configure NVIC. */
////	stcIrqRegiCfg.enIRQn = USART3_RX_FULL_IRQn;
////	stcIrqRegiCfg.enIntSrc = USART3_RX_FULL_INT_SRC;
////	stcIrqRegiCfg.pfnCallback = &USART3_RxFull_IrqCallback;
////	INTC_IrqInstalHandler(&stcIrqRegiCfg, DDL_IRQ_PRIORITY_DEFAULT);
//	
//	
    /*Enable TX && RX function*/
    USART_FuncCmd(USART_CH, UsartTx, Enable);
    USART_FuncCmd(USART_CH, UsartRx, Enable);
    USART_FuncCmd(USART3_CH, UsartTx, Enable);
    USART_FuncCmd(USART3_CH, UsartRx, Enable);
////    USART_FuncCmd(USART3_CH, UsartRxInt, Enable);
//    /*Enable TX && RX function*/
//    USART_FuncCmd(USART_CH, (UsartTx|UsartRx|UsartRxInt), Enable);
//    USART_FuncCmd(USART3_CH, (UsartTx|UsartRx|UsartRxInt), Enable);
}

void uartSendData(uint8_t *data, uint8_t len)
{
    // 等待数据发送完成
    while(DMA_UNIT->MONDTCTL1_f.CNT > 0)
    {
        ;
    }
    // 这里还要再延时一下，否则会丢2个左右的数据
    // 延时时间和波特率有关
    Ddl_Delay1us(100);
 
    USART_FuncCmd(USART_CH, UsartTx, Disable);
    DMA_ChannelCmd(DMA_UNIT, DMA_CH_TX, Disable);
    DMA_SetSrcAddress(DMA_UNIT, DMA_CH_TX,(uint32_t)sendBuf);
    memcpy(sendBuf,data,len);
    DMA_SetTransferCnt(DMA_UNIT, DMA_CH_TX,len);
    DMA_ChannelCmd(DMA_UNIT, DMA_CH_TX, Enable);
    USART_FuncCmd(USART_CH, UsartTx, Enable);
}

void uart3SendData(uint8_t *data, uint8_t len)
{
    // 等待数据发送完成
    while(DMA_UNIT1->MONDTCTL1_f.CNT > 0)
    {
        ;
    }
    // 这里还要再延时一下，否则会丢2个左右的数据
    // 延时时间和波特率有关
    Ddl_Delay1us(100);
 
    USART_FuncCmd(USART3_CH, UsartTx, Disable);
    DMA_ChannelCmd(DMA_UNIT1, DMA_CH_TX, Disable);
    DMA_SetSrcAddress(DMA_UNIT1, DMA_CH_TX,(uint32_t)send3Buf);
    memcpy(send3Buf,data,len);
    DMA_SetTransferCnt(DMA_UNIT1, DMA_CH_TX,len);
    DMA_ChannelCmd(DMA_UNIT1, DMA_CH_TX, Enable);
    USART_FuncCmd(USART3_CH, UsartTx, Enable);
}

uint16_t getRemainRecvBuf(void)
{
    return (RXBUF_LEN - DMA_UNIT->MONRPT0_f.DRPT);
}

uint16_t getRemainRecv3Buf(void)
{
    return (RXBUF_LEN - DMA_UNIT1->MONRPT0_f.DRPT);
}

void restartRx(void)
{
    while(DMA_UNIT->MONDTCTL1_f.CNT > 0)
    {	
        ;	
    }	
    Ddl_Delay1us(100);
    USART_CH->CR1 = (uint32_t)0x801B0000ul;
    USART_SetBaudrate(USART_CH, USART_BAUDRATE);
    USART_FuncCmd(USART_CH, UsartRx, Enable);
}

void restartRx3(void)
{
    while(DMA_UNIT1->MONDTCTL1_f.CNT > 0)
    {	
        ;	
    }	
    Ddl_Delay1us(100);
    USART3_CH->CR1 = (uint32_t)0x801B0000ul;
    USART_SetBaudrate(USART3_CH, USART_BAUDRATE);
    USART_FuncCmd(USART3_CH, UsartRx, Enable);
}

/**
 * @brief  Instal IRQ handler.
 * @param  [in] pstcConfig      Pointer to struct @ref stc_irq_signin_config_t
 * @param  [in] u32Priority     Interrupt priority
 * @retval None
 */
//static void INTC_IrqInstalHandler(const stc_irq_regi_conf_t *pstcConfig, uint32_t u32Priority)
//{
//	if (NULL != pstcConfig) 
//	{
//		(void)enIrqRegistration(pstcConfig);
//		NVIC_SetPriority(pstcConfig->enIRQn, u32Priority);
//		NVIC_ClearPendingIRQ(pstcConfig->enIRQn);
//		NVIC_EnableIRQ(pstcConfig->enIRQn);
//	}
//}

void Usart3RxErrProcess(void)
{
    if (Set == USART_GetStatus(USART3_CH, UsartFrameErr))
    {
        USART_ClearStatus(USART3_CH, UsartFrameErr);
    }
}

void Usart1RxErrProcess(void)
{
    if (Set == USART_GetStatus(USART_CH, UsartFrameErr))
    {
        USART_ClearStatus(USART_CH, UsartFrameErr);
    }
}
uint32_t Debug_Uart_SendDataPoll(uint8_t u8Data)
{
	uint16_t timeout;
	timeout = 0;
	while(++timeout<60000)
	{
	if(USART_GetStatus(USART3_CH, 0x00000080UL)) break;
	}
	USART_SendData(USART3_CH, u8Data);
	timeout = 0;
	while(++timeout<60000)
	{
	if(USART_GetStatus(USART3_CH, 0x00000040UL)) break;
	}
	return 0;
}

int32_t fputc(int32_t ch, FILE *f)
{
    (void)f;  /* Prevent unused argument compilation warning */
    return (0 == Debug_Uart_SendDataPoll((char)ch)) ? ch : -1;
}


